/**
 * 
 */
package idv.takeshi.software.productline.bookstore.presentation.web.controller;

import idv.takeshi.software.productline.bookstore.application.service.MaintainUserAccountService;
import idv.takeshi.software.productline.bookstore.application.service.OriginalPasswordInvalidException;
import idv.takeshi.software.productline.bookstore.application.service.PlaceOrderService;
import idv.takeshi.software.productline.bookstore.application.service.UserRegistrationSerivce;
import idv.takeshi.software.productline.bookstore.application.service.dto.IndividualAccountDto;
import idv.takeshi.software.productline.bookstore.application.service.dto.UserAccountDto;
import idv.takeshi.software.productline.bookstore.domain.model.order.Order;
import idv.takeshi.software.productline.bookstore.domain.model.useraccount.Customer;
import idv.takeshi.software.productline.bookstore.domain.model.useraccount.IndividualAccount;
import idv.takeshi.software.productline.bookstore.domain.model.useraccount.UserAccount;

import java.security.Principal;
import java.util.Locale;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

/**
 * A Controller for member operations.
 * @author takeshi
 *
 */
@Controller("memberController")
@RequestMapping(value = "/member")
public class MemberController {
	
	private static final Log log = LogFactory.getLog(MemberController.class);
	
	@Autowired
	private UserRegistrationSerivce individualAccountRegistrationService;
	
	@Autowired
	private PlaceOrderService placeOrderService;
	
	@Autowired
	private MaintainUserAccountService maintainUserAccountService;
	
	@Autowired
	private MessageSource messageSource;
	
	@RequestMapping(value = "/orders.html", method = RequestMethod.GET)
	public void listOrders(Principal principal, HttpServletRequest request, ModelMap modelMap){
		UserAccount userAccount = null;
		Customer customer = null;
		userAccount = this.individualAccountRegistrationService.getUserAccountByName(principal.getName());
		customer = userAccount.getRole(Customer.class);
		
		modelMap.put("orders", customer.getOrders());
		modelMap.put("previousPath", request.getServletPath());
	}
	
	@RequestMapping(value = "/order.html", method = RequestMethod.GET)
	public void goToAnOrder(@RequestParam Long orderId, ModelMap modelMap){
		Order order = this.placeOrderService.getOrderById(orderId);
		modelMap.put("order", order);
	}
	
	@RequestMapping(value = "/maintainUserInfo.html", method = RequestMethod.GET)
	public void createUserAccountDto(Principal principal, ModelMap modelMap){
		IndividualAccount userAccount = null;
		IndividualAccountDto userAccountDto = null;
		
		userAccount = (IndividualAccount) this.individualAccountRegistrationService.getUserAccountByName(
				principal.getName());
		userAccountDto = new IndividualAccountDto(userAccount);
		
		modelMap.put("userAccountDto", userAccountDto);
	}
	
	@RequestMapping(value = "/maintainUserInfo.html", method = RequestMethod.POST)
	public String updateUserAccount(
			@ModelAttribute("userAccountDto") @Valid final IndividualAccountDto individualAccountDto,
			final BindingResult result, Principal principal, Locale locale){
		if(result.hasErrors()){
			return "/member/maintainUserInfo";
		}
		
		if(!StringUtils.equals(individualAccountDto.getPassword(), individualAccountDto.getConfirmedPassword())){
			result.addError(new FieldError("userAccountDto", "confirmedPassword", 
					messageSource.getMessage("Pattern.userAccountDto.confirmedPassword.notEquals", 
					null, locale)));
		}
		
		if(StringUtils.isNotBlank(individualAccountDto.getNewPassword())){
			if(!StringUtils.equals(individualAccountDto.getNewPassword(), 
					individualAccountDto.getConfirmedNewPassword())){
				result.addError(new FieldError("userAccountDto", "confirmedNewPassword", 
						messageSource.getMessage("Pattern.userAccountDto.confirmedNewPassword.notEquals", 
						null, locale)));
			}
		}
		
		if(result.hasErrors()){
			return "/member/maintainUserInfo";
		}
		
		try {
			this.maintainUserAccountService.updateUserAccount(individualAccountDto);
		} catch (OriginalPasswordInvalidException e) {
			log.warn("user account password:" + individualAccountDto.getPassword() +
					" is invalid");
			
			result.addError(new FieldError("userAccountDto", "password", 
					messageSource.getMessage("Pattern.userAccountDto.password.invalid", 
					null, locale)));
			
			return "/member/maintainUserInfo";
		}
		return "redirect:/member/maintainUserInfo.html?msgCode=member.maintainUserInfo.update.success";
	}

}
